package com.etocrm.saas.lib.base.log.requestlog.interceptor;

import cn.hutool.core.io.IoUtil;
import com.etocrm.saas.lib.base.log.requestlog.util.RequestUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Map;

/**
 * 统一的日志打印
 * Created by Xs on 2022/12/13.
 */
@Slf4j
public class HttpLogInterceptor implements HandlerInterceptor {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        try {
            if (handler instanceof HandlerMethod) {
                String requestURI = request.getRequestURI();
                String queryString = request.getQueryString();

                StringBuilder headerString = new StringBuilder();
                headerString.append("headers : {");
                Iterator<String> stringIterator = request.getHeaderNames().asIterator();
                while (stringIterator.hasNext()) {
                    String headerName = stringIterator.next();
                    String headerValue = request.getHeader(headerName);
                    headerString.append(String.format("(%s:%s),", headerName, headerValue));
                }
                headerString.append("}");


                HandlerMethod handlerMethod = (HandlerMethod) handler;
                String requestMethod = handlerMethod.getMethod().getName();
                Map<String, String[]> parameterMap = request.getParameterMap();


                String requestBody = null;
                if (RequestUtil.isJsonRequest(request)) {
                    ServletInputStream inputStream = request.getInputStream();
                    if (inputStream.markSupported()) {
                        inputStream.mark(0);
                        requestBody = IoUtil.read(request.getInputStream(), StandardCharsets.UTF_8);
                        inputStream.reset();
                    }
                }

                String requestParam = objectMapper.writeValueAsString(parameterMap);
                log.info("====> 请求参数requestURI : {} , requestMethod: {} ", requestURI, requestMethod);
                log.info("====> headers : {}", headerString);
                log.info("====> requestParam, queryString : {} , requestParam : {} , requestBody : {}", queryString, requestParam, requestBody);
            }
        } catch (Exception e) {
            // ignore  注释掉
            log.warn("请求日志生成异常 : " + e.getMessage(), e);
        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}
